home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / SCSIPatch / dcmds / ScsiSendRecord.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-14  |  12.3 KB  |  713 lines  |  [TEXT/MPS ]

  1. /*
  2.     ScsiSendRecord.c
  3.         Copyright Paul Baxter
  4.  
  5.    The following MPW commands will build the dcmd and copy it to the
  6.    "Debugger Prefs" file in the System folder. The dcmd's name in
  7.    MacsBug will be the name of the file built by the Linker.
  8.  
  9.    You must have the following object files in the "{Libraries}" directory:
  10.    dcmdGlue.a.o DRuntime.o put.c.o 
  11.    You must also have the folowing header files in the "{CIncludes}" directory:
  12.    dcmd.h put.h
  13.    
  14.     C ScsisendRecord.c
  15.     Link "{Libraries}"dcmdGlue.a.o scsisendrecord.c.o "{Libraries}"patchlib.a.o "{Libraries}"put.c.o "{Libraries}"DRuntime.o  -o ScsiSendRecord
  16.     BuildDcmd ScsiSendRecord 104
  17.     Echo 'include "ScsiSendRecord";'    |    Rez -a -o "{systemFolder}Debugger Prefs"
  18. */
  19.  
  20. #include <Types.h>
  21. #include <Scsi.h>
  22. #include <Errors.h>
  23. #include <put.h>
  24. #include <dcmd.h>
  25. #include <Patch.h>
  26.  
  27. #define scsiReset        0x0000
  28. #define scsiGet            0x0001
  29. #define scsiSelect        0x0002
  30. #define scsiSelAtn        0x000B
  31. #define scsiCmd            0x0003
  32. #define scsiComplete    0x0004
  33. #define scsiRead        0x0005
  34. #define scsiWrite        0x0006
  35. #define scsiRBlind        0x0008
  36. #define scsiWBlind        0x0009
  37. #define scsiStat        0x000A
  38. #define scsiMsgIn        0x000C
  39. #define scsiMsgOut        0x000D
  40.  
  41.  
  42. #define    TESTUNITREADY    0x00
  43. #define    REQUESTSENSE    0x03
  44. #define    READ            0x08
  45. #define    WRITE            0x0A
  46. #define    SEEK            0x0B
  47. #define    INQUIRY            0x12
  48. #define    MODESELECT        0x15
  49. #define    MODESENSE        0x1A
  50. #define    STARTSTOPUNIT    0x1B
  51. #define    READCAPACITY    0x25
  52. #define    EXTREAD            0x28
  53. #define    EXTSEEK            0x2B
  54. #define    VERIFY            0x2F
  55.  
  56. static OSErr do_reset(Ptr buffer, long* count, long *len);
  57. static OSErr do_get(Ptr buffer, long* count, long *len);
  58. static OSErr do_select(Ptr buffer, long* count, long* len);
  59. static OSErr do_cmd(Ptr buffer, long* count, long* len);
  60. static OSErr do_complete(Ptr buffer, long* count, long* len);
  61. static OSErr do_status(Ptr buffer, long* count, long* len);
  62. static OSErr do_tib(Ptr buffer, long* count, long* len);
  63. static OSErr do_msgout(Ptr buffer, long* count, long* len);
  64. static OSErr do_msgin(Ptr buffer, long* count, long* len);
  65. static OSErr do_data(Ptr buffer, long* count, long* len);
  66. static OSErr do_undefined(Ptr buffer, long* count, long* len);
  67. static void PutSpaces(int count);
  68. static void do_result(unsigned short result);
  69. static void do_pstr_word(char* str, unsigned short value);
  70.  
  71. void PutHexByte (unsigned char number)
  72. {
  73.     char  hex[sizeof(number) << 1 + 1];
  74.     char*    digits = "0123456789ABCDEF";
  75.     int        n;
  76.  
  77.     hex[0] = sizeof(number) << 1;
  78.     for (n = sizeof(number) << 1; n >= 1; n--)
  79.     {
  80.         hex[n] = digits[number % 16];
  81.         number = number / 16;
  82.     }
  83.     PutPStr(hex);
  84. }
  85.  
  86. void PutHexWord (unsigned short number)
  87. {
  88.     
  89.     char  hex[sizeof(number) << 1 + 1];
  90.     char*    digits = "0123456789ABCDEF";
  91.     int        n;
  92.  
  93.     hex[0] = sizeof(number) << 1;
  94.     for (n = sizeof(number) << 1; n >= 1; n--)
  95.     {
  96.         hex[n] = digits[number % 16];
  97.         number = number / 16;
  98.     }
  99.     PutPStr(hex);
  100. }
  101.  
  102. void PutHexLong (unsigned long number)
  103. {
  104.     char  hex[sizeof(number) << 1 + 1];
  105.     char*    digits = "0123456789ABCDEF";
  106.     int        n;
  107.  
  108.     hex[0] = sizeof(number) << 1;
  109.     for (n = sizeof(number) << 1; n >= 1; n--)
  110.     {
  111.         hex[n] = digits[number % 16];
  112.         number = number / 16;
  113.     }
  114.     PutPStr(hex);
  115. }
  116.  
  117. void PutSpaces(int count)
  118. {
  119.     for (;count--;) {
  120.         PutSpace();
  121.     }
  122. }
  123.  
  124. void do_pstr_word(char* str, unsigned short value)
  125. {
  126.     PutPStr(str);
  127.     PutSpace();
  128.     PutHexWord(value);
  129.     PutSpace();
  130. }
  131.  
  132. pascal void CommandEntry (dcmdBlock* paramPtr)
  133. {
  134.     OSErr err;
  135.     Ptr buffer;
  136.     long count,len;
  137.  
  138.     switch (paramPtr->request)
  139.         {
  140.         case dcmdInit:
  141.             break;
  142.  
  143.         case dcmdHelp:
  144.             dcmdDrawLine ("\pScsiSendRecord");
  145.             dcmdDrawLine ("\p   Display Recording buffer.");
  146.             break;
  147.  
  148.         case dcmdDoIt:
  149.             err = SCSISENDRECORD(&buffer, &count);
  150.             if (err == unimpErr) {
  151.                 dcmdDrawLine ("\pSCSI Patch not Installed.");
  152.             }
  153.             else {
  154.                 dcmdDrawLine ("\pSCSI Recording Buffer:");
  155.                 for (;count > 0L;) {
  156.                     short cmd;
  157.                     
  158.                     cmd = *(short*)buffer;
  159.                     switch (cmd) {
  160.                         case scsiReset:
  161.                             err = do_reset(buffer, &count, &len);
  162.                             break;
  163.     
  164.                         case scsiGet:
  165.                             err = do_get(buffer, &count, &len);
  166.                             break;
  167.                             
  168.                         case scsiSelect:
  169.                         case scsiSelAtn:
  170.                             err = do_select(buffer, &count, &len);
  171.                             break;
  172.     
  173.                         case scsiStat:
  174.                             err = do_status(buffer, &count, &len);
  175.                             break;
  176.     
  177.                         case scsiCmd:
  178.                             err = do_cmd(buffer, &count, &len);
  179.                             break;
  180.     
  181.                         case scsiRead:
  182.                         case scsiWrite:
  183.                         case scsiRBlind:
  184.                         case scsiWBlind:
  185.                             err = do_tib(buffer, &count, &len);
  186.                             break;
  187.     
  188.                         case scsiComplete:
  189.                             err = do_complete(buffer, &count, &len);
  190.                             break;
  191.                             
  192.                         case scsiMsgIn:
  193.                             err = do_msgin(buffer, &count, &len);
  194.                             break;
  195.     
  196.                         case scsiMsgOut:
  197.                             err = do_msgout(buffer, &count, &len);
  198.                             break;
  199.     
  200.                         case data_opcode:
  201.                             err = do_data(buffer, &count, &len);
  202.                             break;
  203.  
  204.                         default:
  205.                             err = do_undefined(buffer, &count, &len);
  206.                             break;
  207.                     }
  208.                     buffer += len;
  209.                 }
  210.                 dcmdDrawLine ("\pEnd.");
  211.                 if (err != 0) {
  212.                     dcmdDrawLine ("\pWarning Record Buffer Full.");
  213.                 }
  214.             }
  215.         }
  216. } // CommandEntry
  217.  
  218.  
  219. OSErr do_undefined(Ptr buffer, long* count, long* len)
  220. {
  221.     
  222.     PutLine();
  223.     do_pstr_word("\pUnknown SCSIDispatch Selector",*((unsigned short*)buffer));
  224.     PutLine();
  225.     *len = 2L;
  226.     if (*count > 1L) {
  227.         *count -= *len;
  228.     }
  229.     else {
  230.         *count = 0L;
  231.         return -1;
  232.     }
  233.     return noErr;
  234. }
  235.  
  236. OSErr do_reset(Ptr buffer, long* count, long* len)
  237. {    
  238.     PutPStr("\pscsiReset");
  239.     PutSpaces(4);
  240.  
  241.     *len = 4L;
  242.     if (*count > 3L) {
  243.         *count -= *len;
  244.         buffer += 2L;
  245.     }
  246.     else {
  247.         PutLine();
  248.         *count = 0L;
  249.         return -1;
  250.     }
  251.     do_result(*((unsigned short*)buffer));
  252.     return noErr;
  253. }
  254.  
  255. OSErr do_get(Ptr buffer, long* count, long* len)
  256. {
  257.     PutLine();
  258.     
  259.     PutPStr("\pscsiGet");
  260.     PutSpaces(7);
  261.     
  262.     *len = 4L;
  263.     if (*count > 3L) {
  264.         *count -= *len;
  265.         buffer += 2L;
  266.     }
  267.     else {
  268.         PutLine();
  269.         *count = 0L;
  270.         return -1;
  271.     }
  272.  
  273.     do_result(*((unsigned short*)buffer));
  274.     return noErr;
  275. }
  276.  
  277. OSErr do_select(Ptr buffer, long* count, long* len)
  278. {
  279.     if (*(short*)buffer == scsiSelect) {
  280.         PutPStr("\pscsiSelect");
  281.         PutSpaces(3);
  282.     }
  283.     else {
  284.         PutPStr("\pscsiSelectAtn");
  285.     }
  286.     PutSpace();
  287.  
  288.     *len = 6L;
  289.     if (*count > 5L) {
  290.         *count -= *len;
  291.         buffer += 2L;
  292.     }
  293.     else {
  294.         PutLine();
  295.         *count = 0L;
  296.         return -1;
  297.     }
  298.  
  299.     PutHexWord(*((unsigned short*)buffer));
  300.     PutSpace();
  301.     buffer += 2L;
  302.     do_result(*((unsigned short*)buffer));
  303.     return noErr;
  304. }
  305.  
  306. OSErr do_cmd(Ptr buffer, long* count, long* len)
  307. {
  308.     short numbytes, cmd_count;
  309.     
  310.     PutPStr("\pscsiCmd");
  311.     PutSpaces(7);
  312.     
  313.     *len = 2L;
  314.     if (*count > 1L) {
  315.         *count -= *len;
  316.         buffer += 2L;
  317.     }
  318.     else {
  319.         PutLine();
  320.         *count = 0L;
  321.         return -1;
  322.     }
  323.     numbytes = *(short*)buffer;
  324.     if (*count >= (long)(numbytes + 4)) {
  325.         *count -= (long)(numbytes + 4);
  326.         *len += (long)(numbytes + 4);
  327.         buffer += 2L;
  328.     }
  329.     else {
  330.         PutLine();
  331.         *count = 0L;
  332.         return -1;
  333.     }
  334.     cmd_count = 0;
  335.     for (;numbytes; numbytes--, buffer++, cmd_count++) {
  336.         if (cmd_count == 0) {
  337.             switch (*buffer) {
  338.                 case TESTUNITREADY:
  339.                     PutPStr("\pTESTUNITREADY");
  340.                     break;
  341.  
  342.                 case REQUESTSENSE:
  343.                     PutPStr("\pREQUESTSENCE");
  344.                     break;
  345.  
  346.                 case READ:
  347.                     PutPStr("\pREAD");
  348.                     break;
  349.  
  350.                 case WRITE:
  351.                     PutPStr("\pWRITE");
  352.                     break;
  353.  
  354.                 case SEEK:
  355.                     PutPStr("\pSEEK");
  356.                     break;
  357.  
  358.                 case INQUIRY:
  359.                     PutPStr("\pINQUIRY");
  360.                     break;
  361.  
  362.                 case MODESELECT:
  363.                     PutPStr("\pMODESELECT");
  364.                     break;
  365.  
  366.                 case MODESENSE:
  367.                     PutPStr("\pMODESENSE");
  368.                     break;
  369.  
  370.                 case STARTSTOPUNIT:
  371.                     PutPStr("\pSTARTSTOPUNIT");
  372.                     break;
  373.  
  374.                 case READCAPACITY:
  375.                     PutPStr("\pREADCAPACITY");
  376.                     break;
  377.  
  378.                 case EXTREAD:
  379.                     PutPStr("\pEXTENDED_READ");
  380.                     break;
  381.  
  382.                 case EXTSEEK:
  383.                     PutPStr("\pEXTENDED_SEEK");
  384.                     break;
  385.  
  386.                 case VERIFY:
  387.                     PutPStr("\pVERIFY");
  388.                     break;
  389.  
  390.                 default:
  391.                     PutHexByte(*buffer);
  392.                     break;
  393.             }
  394.         }
  395.         else {
  396.             PutHexByte(*buffer);
  397.         }
  398.         PutSpace();
  399.     }
  400.     
  401.     do_result(*((unsigned short*)buffer));
  402.     return noErr;
  403. }
  404.  
  405. OSErr do_tib(Ptr buffer, long* count, long* len)
  406. {
  407.     short scsi_tib_op, tib_count;
  408.  
  409.     switch (*(short*)buffer) {
  410.         case scsiRead:
  411.             PutPStr("\pscsiRead");
  412.             PutSpaces(3);
  413.             break;
  414.         
  415.         case scsiWrite:
  416.             PutPStr("\pscsiWrite");
  417.             PutSpaces(2);
  418.             break;
  419.         
  420.         case scsiRBlind:
  421.             PutPStr("\pscsiRBlind");
  422.             PutSpace();
  423.             break;
  424.     
  425.         case scsiWBlind:
  426.             PutPStr("\pscsiWBlind");
  427.             PutSpace();
  428.             break;
  429.     }
  430.     *len = 2L;
  431.     if (*count > 1L) {
  432.         *count -= *len;
  433.         buffer += 2L;
  434.     }
  435.     else {
  436.         *count = 0L;
  437.         return -1;
  438.     }
  439.     tib_count = 0;
  440.     do {
  441.         *len += 10L;
  442.         if (*count > 9L) {
  443.             *count -= 10L;
  444.         }
  445.         else {
  446.             *count = 0L;
  447.             return -1;
  448.         }
  449.         scsi_tib_op = *(short*)buffer;
  450.         buffer += 2L;
  451.         PutSpaces(3);
  452.         if (tib_count > 0) {
  453.             PutSpaces(11);
  454.         }
  455.         switch (scsi_tib_op) {
  456.             case scInc:
  457.                 PutPStr("\pscInc");
  458.                 PutSpaces(3);
  459.                 break;
  460.  
  461.             case scNoInc:
  462.                 PutPStr("\pscNoInc");
  463.                 PutSpace();
  464.                 break;
  465.  
  466.             case scAdd:
  467.                 PutPStr("\pscAdd");
  468.                 PutSpaces(3);
  469.                 break;
  470.  
  471.             case scMove:
  472.                 PutPStr("\pscMove");
  473.                 PutSpaces(2);
  474.                 break;
  475.  
  476.             case scLoop:
  477.                 PutPStr("\pscLoop");
  478.                 PutSpaces(2);
  479.                 break;
  480.  
  481.             case scNop:
  482.                 PutPStr("\pscNop");
  483.                 PutSpaces(3);
  484.                 break;
  485.  
  486.             case scStop:
  487.                 PutPStr("\pscStop");
  488.                 PutSpaces(2);
  489.                 break;
  490.  
  491.             case scComp:
  492.                 PutPStr("\pscComp");
  493.                 PutSpaces(2);
  494.                 break;
  495.  
  496.             default:
  497.                 PutPStr("\pTib Corrupt!");
  498.                 PutLine();
  499.                 *count = 0L;
  500.                 return -1;
  501.                 break;
  502.         }
  503.  
  504.         PutHexLong(*((unsigned long*)buffer));
  505.         PutSpace();
  506.         buffer += 4L;
  507.         PutHexLong(*((unsigned long*)buffer));
  508.         if (scsi_tib_op != scStop) {
  509.             PutLine();
  510.         }
  511.         buffer += 4L;
  512.         tib_count++;
  513.     } while (scsi_tib_op != scStop);
  514.     
  515.     *len += 2L;
  516.     if (*count > 1L) {
  517.         *count -= 2L;
  518.     }
  519.     else {
  520.         *count = 0L;
  521.         return -1;
  522.     }
  523.  
  524.     PutSpace();
  525.     do_result(*((unsigned short*)buffer));
  526.     return noErr;
  527. }
  528.  
  529. OSErr do_complete(Ptr buffer, long* count, long* len)
  530. {
  531.     PutPStr("\pscsiComplete");
  532.     PutSpaces(2);
  533.  
  534.     *len = 20L;
  535.     if (*count > 19L) {
  536.         *count -= *len;
  537.         buffer += 10L;
  538.     }
  539.     else {
  540.         PutLine();
  541.         *count = 0L;
  542.         return -1;
  543.     }
  544.     PutPStr("\pTime");
  545.     PutSpace();
  546.     PutHexLong(*((unsigned long*)buffer));
  547.     PutSpace();
  548.     buffer += 4L;
  549.  
  550.     do_pstr_word("\pStatus", *((unsigned short*)buffer));
  551.     buffer += 2L;
  552.     do_pstr_word("\pMessage", *((unsigned short*)buffer));
  553.     buffer += 2L;
  554.     do_result(*((unsigned short*)buffer));
  555.     return noErr;
  556. }
  557.  
  558. OSErr do_msgout(Ptr buffer, long* count, long* len)
  559. {
  560.     PutPStr("\pscsiMsgOut");
  561.     PutSpaces(4);
  562.  
  563.     *len = 6L;
  564.     if (*count > 5L) {
  565.         *count -= *len;
  566.         buffer += 2L;
  567.     }
  568.     else {
  569.         PutLine();
  570.         *count = 0L;
  571.         return -1;
  572.     }
  573.     do_pstr_word("\pMessage", *((unsigned short*)buffer));
  574.     buffer += 2L;
  575.     do_result(*((unsigned short*)buffer));
  576.     return noErr;
  577. }
  578.  
  579. OSErr do_msgin(Ptr buffer, long* count, long* len)
  580. {
  581.     PutPStr("\pscsiMsgIn");
  582.     PutSpaces(5);
  583.  
  584.     *len = 10L;
  585.     if (*count > 9L) {
  586.         *count -= *len;
  587.         buffer += 6L;
  588.     }
  589.     else {
  590.         PutLine();
  591.         *count = 0L;
  592.         return -1;
  593.     }
  594.     do_pstr_word("\pMessage", *((unsigned short*)buffer));
  595.     buffer += 2L;
  596.     do_result(*((unsigned short*)buffer));
  597.     return noErr;
  598. }
  599.  
  600. OSErr do_status(Ptr buffer, long* count, long* len)
  601. {
  602.     
  603.     PutPStr("\pscsiStat");
  604.     PutSpaces(6);
  605.     
  606.     *len = 4L;
  607.     if (*count > 3L) {
  608.         *count -= *len;
  609.         buffer += 2L;
  610.     }
  611.     else {
  612.         PutLine();
  613.         *count = 0L;
  614.         return -1;
  615.     }
  616.     do_pstr_word("\pStatus Word", *((unsigned short*)buffer));
  617.     PutLine();
  618.     return noErr;
  619. }
  620.  
  621. OSErr do_data(Ptr buffer, long* count, long* len)
  622. {
  623.     short data_len, cnt;
  624.     
  625.     PutPStr("\pscsiData");
  626.     PutSpaces(6);
  627.     
  628.     *len = 4L;
  629.     if (*count > 3L) {
  630.         *count -= *len;
  631.         buffer += 2L;
  632.     }
  633.     else {
  634.         PutLine();
  635.         *count = 0L;
  636.         return -1;
  637.     }
  638.  
  639.     data_len = *((unsigned short*)buffer);
  640.     buffer += 2L;
  641.     *len += (long)data_len;
  642.     if (*count >= (long)data_len) {
  643.         *count -= (long)data_len;
  644.     }
  645.     else {
  646.         PutLine();
  647.         *count = 0L;
  648.         return -1;
  649.     }
  650.  
  651.     for (cnt = 1;data_len; cnt++, data_len--, buffer++) {
  652.         PutHexByte(*buffer);
  653.         PutSpace();
  654.         if ((cnt % 16) == 0) {
  655.             PutLine();
  656.             PutSpaces(14);
  657.         }
  658.     }
  659.     PutLine();
  660.     return noErr;
  661. }
  662.  
  663. void do_result(unsigned short result)
  664. {
  665.     PutPStr("\p:");
  666.     PutSpace();
  667.     switch (result) {
  668.         case noErr:
  669.             PutPStr("\pnoErr");
  670.             break;
  671.         
  672.         case scCommErr:
  673.             PutPStr("\pscCommErr");
  674.             break;
  675.  
  676.         case scArbNBErr:
  677.             PutPStr("\pscArbNBErr");
  678.             break;
  679.  
  680.         case scBadParmsErr:
  681.             PutPStr("\pscBadParmsErr");
  682.             break;
  683.  
  684.         case scPhaseErr:
  685.             PutPStr("\pscPhaseErr");
  686.             break;
  687.  
  688.         case scCompareErr:
  689.             PutPStr("\pscCompareErr");
  690.             break;
  691.  
  692.         case scMgrBusyErr:
  693.             PutPStr("\pscMgrBusyErr");
  694.             break;
  695.  
  696.         case scSequenceErr:
  697.             PutPStr("\pscSequenceErr");
  698.             break;
  699.  
  700.         case scBusTOErr:
  701.             PutPStr("\pscBusTOErr");
  702.             break;
  703.  
  704.         case scComplPhaseErr:
  705.             PutPStr("\pscComplPhaseErr");
  706.             break;
  707.  
  708.         default:
  709.             PutHexWord(result);
  710.             break;
  711.     }
  712.     PutLine();
  713. }